package com.mmall.service;

import com.google.common.base.Preconditions;
import com.mmall.common.RequestHolder;
import com.mmall.dao.SysAclMapper;
import com.mmall.dao.SysAclModuleMapper;
import com.mmall.exception.ParamException;
import com.mmall.model.SysAclModule;
import com.mmall.param.AclModuleParam;
import com.mmall.util.BeanValidator;
import com.mmall.util.IpUtil;
import com.mmall.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * Created by asus on 2018/4/8.
 */
@Service
public class SysAclModuleService {

    @Resource
    private SysAclModuleMapper sysAclModuleMapper;
    @Resource
    private SysAclMapper sysAclMapper;
    @Resource
    private SysLogService sysLogService;

    public void save(AclModuleParam param){
        BeanValidator.check(param);
        if(checkExist(param.getParentId(),param.getName(),param.getId())){
            throw new ParamException("同一层级下存在相同名称的权限模块");
        }
        SysAclModule aclModule = SysAclModule.builder().name(param.getName()).parentId(param.getParentId()).remark(param.getRemark())
                .seq(param.getSeq()).status(param.getStatus()).build();

        aclModule.setLevel(LevelUtil.calculateLevel(getLevel(param.getParentId()),param.getParentId()));
        aclModule.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        aclModule.setOperator(RequestHolder.getCurrentUser().getUsername());
        aclModule.setOperateTime(new Date());
        sysAclModuleMapper.insertSelective(aclModule);
        sysLogService.saveAclModuleLog(null,aclModule);
    }

    public void update(AclModuleParam param){
        BeanValidator.check(param);
        if(checkExist(param.getParentId(),param.getName(),param.getId())){
            throw new ParamException("同一层级下存在相同名称的权限模块");
        }
        SysAclModule before = sysAclModuleMapper.selectByPrimaryKey(param.getId());
        Preconditions.checkNotNull(before,"待更新的权限模块不存在");

        SysAclModule after = SysAclModule.builder().id(param.getId()).parentId(param.getParentId()).status(param.getStatus()).remark(param.getRemark())
                .name(param.getName()).seq(param.getSeq()).build();
        after.setLevel(LevelUtil.calculateLevel(getLevel(param.getParentId()),param.getParentId()));
        after.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        after.setOperator(RequestHolder.getCurrentUser().getUsername());
        after.setOperateTime(new Date());
        updateWithChild(before,after);
        sysLogService.saveAclModuleLog(before,after);
    }

    private void updateWithChild(SysAclModule before,SysAclModule after){
        String oldLevelPrefix = before.getLevel();
        String newLevelPrefix = after.getLevel();
        if(!newLevelPrefix.equals(oldLevelPrefix)){
            List<SysAclModule> aclModuleList = sysAclModuleMapper.getChildAclModuleListByLevel(oldLevelPrefix);
            if(CollectionUtils.isNotEmpty(aclModuleList)){
                for(SysAclModule aclModule : aclModuleList){
                    String level = aclModule.getLevel();
                    if(level.indexOf(oldLevelPrefix) == 0){
                        level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                        aclModule.setLevel(level);
                    }
                }
                sysAclModuleMapper.batchUpdateLevel(aclModuleList);
            }
        }
        sysAclModuleMapper.updateByPrimaryKey(after);
    }

    private boolean checkExist(Integer parentId,String name, Integer id){
        return sysAclModuleMapper.countByNameAndParentId(parentId,name,id)>0;
    }

    private String getLevel(Integer id){
        SysAclModule aclModule = sysAclModuleMapper.selectByPrimaryKey(id);
        if(aclModule == null){
            return null;
        }
        return aclModule.getLevel();
    }

    public void delete(Integer aclModuleId){
        SysAclModule sysAclModule = sysAclModuleMapper.selectByPrimaryKey(aclModuleId);
        Preconditions.checkNotNull(sysAclModule,"要删除的权限模块不存在");
        if(sysAclModuleMapper.countByParentId(sysAclModule.getId())>0){
            throw new ParamException("该权限模块下存在权限模块，无法删除");
        }
        if(sysAclMapper.countByAclModuleId(sysAclModule.getId())>0){
            throw new ParamException("该权限模块下存在权限点，无法删除");
        }
        sysAclModuleMapper.deleteByPrimaryKey(sysAclModule.getId());
        sysLogService.saveAclModuleLog(sysAclModule,null);
    }
}
